// 其中最核心的就是ServerState,注意到他被放在了 Arc<Mutex>中,这也就意味着
// 他要多线程访问
// 多线程中读写
// 如果一个复杂结构体,需要多线程读,我们可以使用Arc包裹,避免多次内存分配
// 如果一个变量,需要多线程读写,我们必须使用Mutex包裹,否则肯定无法编译
// 这里的SubListTrait就是上节课从零实现消息中间件-sublist中讲到的.

// pub struct ServerState<T: SubListTrait> {
//     clients: HashMap<u64, Arc<Mutex<ClientMessage>>>,
// }

use crate::client::*;
use crate::simple_sublist::SubListTrait;
use std::collections::HashMap;
use std::error::Error;
use std::sync::Arc;
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::Mutex;

#[derive(Debug, Default)]
pub struct Server<T: SubListTrait> {
    state: Arc<Mutex<ServerState<T>>>,
}
#[derive(Debug, Default)]
pub struct ServerState<T: SubListTrait> {
    clients: HashMap<u64, Arc<Mutex<ClientMessageSender>>>,
    pub sublist: T,
    pub gen_cid: u64,
}

impl<T: SubListTrait + Send + 'static> Server<T> {
    pub async fn start(self) -> Result<(), Box<dyn Error>> {
        let addr = "0.0.0.0:4222";
        let mut listener = TcpListener::bind(addr).await?;
        //go func(){}
        loop {
            let (conn, _) = listener.accept().await?;
            self.new_client(conn).await;
        }
    }
    async fn new_client(&self, conn: TcpStream) {
        let state = self.state.clone();
        let cid = {
            let mut state = state.lock().await;
            state.gen_cid += 1;
            state.gen_cid
        };
        let _c = Client::process_connection(cid, state, conn);
        //        self.state.lock().await.clients.insert(cid, c);
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn test() {}
}